﻿using Core.Utility.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Core.Utility.Helper
{
    /// <summary>
    /// 命名助手类
    /// </summary>
    public static class NamespaceHelper
    {
        /// <summary>
        /// 命名助手类-字符串转英语单词列表，优先使用符号分割列表进行分割，再尝试使用正则根据单词大小写进行分割;
        /// <para>实现原理参考：<see href="https://github.com/imdong/Var-Conv/blob/main/src/var-conv.js"/></para>
        /// </summary>
        /// <param name="value"></param>
        /// <param name="symbolSplitList">符号分割列表，为null默认分割 -,_,空格,为 new List&lt;char&gt;() 则不使用符号分隔符 </param>
        /// <returns></returns>
        public static List<string> ToEnglishWordList(this string value,List<char>? symbolSplitList = null)
        {
            value = value.Trim().Replace("\n","").Replace("\r\n","").Replace("\t","");
            List<string> wordList = new List<string>();
            //符号拆分单词列表
            List<string> symbolSplitWordList = new List<string>();
            if(symbolSplitList == null)
            {
                symbolSplitList = new List<char>()
                {
                    '-',
                    '_',
                    ' ',
                };
            }
            // 拆分符号列表
            symbolSplitList.ForEach((splitter) => {
                if (value.IndexOf(splitter) > 0)
                {
                    symbolSplitWordList = value.Split(splitter).ToList();
                    foreach(var symbolSplitWordItem in symbolSplitWordList)
                    {
                        if(!wordList.Contains(symbolSplitWordItem))
                        {
                            wordList.Add(symbolSplitWordItem);
                        }
                    }
                }
            });

            if (wordList.Count <= 0)
            {
                // 拆分符号无法拆分，使用正则表达式 大小写拆
                //Regex regex = new Regex("(^[A-Z]|^|[A-Z])([a-z]+)?");
                Regex regex = new Regex("(^[A-Z]|^|[A-Z0-9])([a-z0-9]+)?");
                var regexMatchRes = regex.Matches(value.Replace(" ", ""));
                if(regexMatchRes.Count > 0)
                {
                    foreach(Match regexMatchItem in regexMatchRes)
                    {
                        wordList.Add(regexMatchItem.Value);
                    }
                }
            }

            if(!string.IsNullOrEmpty(value) && wordList.Count <= 0)
            {
                wordList.Add(value);
            }
            return wordList;
        }

        /// <summary>
        /// 切割骆驼命名式字符串
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static List<string> SplitCamelCase(this string str)
        {
            if (str == null)
            {
                return new List<string>();
            }

            if (string.IsNullOrWhiteSpace(str))
            {
                return new List<string> { str };
            }
            if (str.Length == 1)
            {
                return new List<string> { str };
            }

            return Regex.Split(str, @"(?=\p{Lu}\p{Ll})|(?<=\p{Ll})(?=\p{Lu})")
                .Where(u => u.Length > 0).ToList();
        }
        /// <summary>
        /// 命名助手类-大驼峰写法 (帕斯卡命名法) UserName
        /// </summary>
        /// <param name="source">源</param>
        /// <param name="symbolSplitList">符号分割列表，为null默认分割 -,_,空格,为 new List&lt;char&gt;() 则不使用符号分隔符 </param>
        /// <returns></returns>
        public static string ToPascalNamespace(this string source, List<char>? symbolSplitList = null)
        {
            if (string.IsNullOrEmpty(source))
            {
                return source;
            }
            List<string> wordList = ToEnglishWordList(source, symbolSplitList);
            StringBuilder sbJoiningTogether = new StringBuilder();
            foreach (string item in wordList)
            {
                sbJoiningTogether.Append(FirstLetterConvertToUpper(item));
            }
            return sbJoiningTogether.ToString();
        }

        /// <summary>
        /// 命名助手类-小驼峰写法 (驼峰命名法) userName
        /// </summary>
        /// <param name="source">源</param>
        /// <param name="symbolSplitList">符号分割列表，为null默认分割 -,_,空格,为 new List&lt;char&gt;() 则不使用符号分隔符 </param>
        /// <returns></returns>
        public static string ToCamelNamespace(this string source, List<char>? symbolSplitList = null)
        {
            if (string.IsNullOrEmpty(source))
            {
                return source;
            }
            List<string> wordList = ToEnglishWordList(source, symbolSplitList);
            StringBuilder sbJoiningTogether = new StringBuilder();
            for (int i = 0; i < wordList.Count; i++)
            {
                if (i == 0)
                {
                    sbJoiningTogether.Append(wordList[i].ToLower());
                }
                else
                {
                    sbJoiningTogether.Append(FirstLetterConvertToUpper(wordList[i]));
                }
            }
            return sbJoiningTogether.ToString();
        }

        /// <summary>
        /// 命名助手类-蛇形写法 (下划线) user_name
        /// </summary>
        /// <param name="source">源</param>
        /// <param name="symbolSplitList">符号分割列表，为null默认分割 -,_,空格,为 new List&lt;char&gt;() 则不使用符号分隔符 </param>
        /// <returns></returns>
        public static string ToSnakeNamespace(this string source, List<char>? symbolSplitList = null)
        {
            return ToJoinStringLowerNamespace(source, "_", symbolSplitList);
        }

        /// <summary>
        /// 命名助手类-连字符写法 user-name
        /// </summary>
        /// <param name="source">源</param>
        /// <param name="symbolSplitList">符号分割列表，为null默认分割 -,_,空格,为 new List&lt;char&gt;() 则不使用符号分隔符 </param>
        /// <returns></returns>
        public static string ToHyphenNamespace(this string source, List<char>? symbolSplitList = null)
        {
            return ToJoinStringLowerNamespace(source, "-", symbolSplitList);
        }

        /// <summary>
        /// 命名助手类-连字符(大写)写法 USER-NAME
        /// </summary>
        /// <param name="source">源</param>
        /// <param name="symbolSplitList">符号分割列表，为null默认分割 -,_,空格,为 new List&lt;char&gt;() 则不使用符号分隔符 </param>
        /// <returns></returns>
        public static string ToHyphenUpperNamespace(this string source, List<char>? symbolSplitList = null)
        {
            return ToJoinStringUpperNamespace(source, "-", symbolSplitList);
        }

        /// <summary>
        /// 命名助手类-常量写法 (全大写下划线) USER_NAME
        /// </summary>
        /// <param name="source">源</param>
        /// <param name="symbolSplitList">符号分割列表，为null默认分割 -,_,空格,为 new List&lt;char&gt;() 则不使用符号分隔符 </param>
        /// <returns></returns>
        public static string ToConstNamespace(this string source, List<char>? symbolSplitList = null)
        {
            return ToJoinStringUpperNamespace(source,"_",symbolSplitList);
        }

        /// <summary>
        /// 命名助手类-连接字符串全小写写法 user连接字符串name
        /// </summary>
        /// <param name="source">源</param>
        /// <param name="joinString">连接字符串，为null则使用-</param>
        /// <param name="symbolSplitList">符号分割列表，为null默认分割 -,_,空格,为 new List&lt;char&gt;() 则不使用符号分隔符 </param>
        /// <returns></returns>
        public static string ToJoinStringLowerNamespace(this string source,string joinString = "-", List<char>? symbolSplitList = null)
        {
            if (string.IsNullOrEmpty(source))
            {
                return source;
            }
            
            List<string> wordList = ToEnglishWordList(source, symbolSplitList);
            for (int i = wordList.Count - 1; i >= 0; i--)
            {
                wordList[i] = wordList[i].ToLower();
            }
            return string.Join(joinString, wordList);
        }

        /// <summary>
        /// 命名助手类-连接字符串全大写写法 USER连接字符串NAME
        /// </summary>
        /// <param name="source">源</param>
        /// <param name="joinString">连接字符串，为null则使用-</param>
        /// <param name="symbolSplitList">符号分割列表，为null默认分割 -,_,空格,为 new List&lt;char&gt;() 则不使用符号分隔符 </param>
        /// <returns></returns>
        public static string ToJoinStringUpperNamespace(this string source, string joinString = "-", List<char>? symbolSplitList = null)
        {
            if (string.IsNullOrEmpty(source))
            {
                return source;
            }

            List<string> wordList = ToEnglishWordList(source, symbolSplitList);
            for (int i = wordList.Count - 1; i >= 0; i--)
            {
                wordList[i] = wordList[i].ToUpper();
            }
            return string.Join(joinString, wordList);
        }

        /// <summary>
        /// 命名助手类-全大写写法 USERNAME
        /// </summary>
        /// <param name="source">源</param>
        /// <param name="symbolSplitList">符号分割列表，为null默认分割 -,_,空格,为 new List&lt;char&gt;() 则不使用符号分隔符 </param>
        /// <returns></returns>
        public static string ToUpperNamespace(this string source, List<char>? symbolSplitList = null)
        {
            if (string.IsNullOrEmpty(source))
            {
                return source;
            }
            List<string> wordList = ToEnglishWordList(source, symbolSplitList);
            for (int i = wordList.Count - 1; i >= 0; i--)
            {
                wordList[i] = wordList[i].ToUpper();
            }
            return string.Join("", wordList);
        }

        /// <summary>
        /// 命名助手类-全小写写法 username
        /// </summary>
        /// <param name="source">源</param>
        /// <param name="symbolSplitList">符号分割列表，为null默认分割 -,_,空格,为 new List&lt;char&gt;() 则不使用符号分隔符 </param>
        /// <returns></returns>
        public static string ToLowerNamespace(this string source, List<char>? symbolSplitList = null)
        {
            if (string.IsNullOrEmpty(source))
            {
                return source;
            }
            List<string> wordList = ToEnglishWordList(source, symbolSplitList);
            for (int i = wordList.Count - 1; i >= 0; i--)
            {
                wordList[i] = wordList[i].ToLower();
            }
            return string.Join("", wordList);
        }

        /// <summary>
        /// 首字母转为大写
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string FirstLetterConvertToUpper(this string source)
        {
            string strRes = source.Trim();
            if (!string.IsNullOrEmpty(strRes))
            {
                string firstLetter = strRes.Substring(0, 1).ToUpper();
                if (strRes.Length > 1)
                {
                    strRes = firstLetter + strRes.Substring(1, strRes.Length - 1).Trim();
                }
                else
                {
                    strRes = firstLetter;
                };
            }
            return strRes;
        }

        /// <summary>
        /// 首字母转为大写，其余字母转为小写;
        /// 如GET => Get
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string FirstLetterConvertToUpperAndOtherToLower(this string source)
        {
            string strRes = source.Trim();
            if (!string.IsNullOrEmpty(strRes))
            {
                string firstLetter = strRes.Substring(0, 1).ToUpper();
                if (strRes.Length > 1)
                {
                    strRes = firstLetter + strRes.Substring(1, strRes.Length - 1).ToLower().Trim();
                }
                else
                {
                    strRes = firstLetter;
                };
            }
            return strRes;
        }

        /// <summary>
        /// 首字母转为小写
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string FirstLetterConvertToLower(this string source)
        {
            string strRes = source.Trim();
            if (!string.IsNullOrEmpty(strRes))
            {
                string firstLetter = strRes.Substring(0, 1).ToLower();
                if (strRes.Length > 1)
                {
                    strRes = firstLetter + strRes.Substring(1, strRes.Length - 1).Trim();
                }
                else
                {
                    strRes = firstLetter;
                };
            }
            return strRes;
        }
    }

    /// <summary>
    /// 命名规则枚举值
    /// </summary>
    public enum NamespaceRulesEnum
    {
        /// <summary>
        /// 无，保持原样
        /// </summary>
        [CodeValueDescription(order: 1, code: "None", value: "1", description: "无")]
        None = 1,

        /// <summary>
        /// 帕斯卡(大驼峰) UserName
        /// </summary>
        [CodeValueDescription(order: 2, code: "Pascal", value: "2", description: "帕斯卡(大驼峰)")]
        Pascal = 2,

        /// <summary>
        /// 小驼峰(驼峰) userName
        /// </summary>
        [CodeValueDescription(order: 3, code: "Camel", value: "3", description: "小驼峰(驼峰)")]
        Camel = 3,

        /// <summary>
        /// 蛇形 user_name
        /// </summary>
        [CodeValueDescription(order: 4, code: "Snake", value: "4", description: "蛇形(驼峰)")]
        Snake = 4,

        /// <summary>
        /// 常量 USER_NAME
        /// </summary>
        [CodeValueDescription(order: 5, code: "Const", value: "5", description: "常量")]
        Const = 5,

        /// <summary>
        /// 连字符(小写) user-name
        /// </summary>
        [CodeValueDescription(order: 6, code: "Hyphen", value: "6", description: "连字符(小写)")]
        Hyphen = 6,


        /// <summary>
        /// 连字符(大写) USER-NAME
        /// </summary>
        [CodeValueDescription(order: 7, code: "HyphenUpper", value: "7", description: "连字符(大小)")]
        HyphenUpper = 7,
    }
}
